package cn.abcsys.cloud.devops.monitor.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import cn.abcsys.cloud.devops.monitor.common.HttpClient;
import cn.abcsys.cloud.devops.monitor.common.SystemConfig;
import cn.abcsys.cloud.devops.monitor.core.impl.MonitorCoreImpl;
import cn.abcsys.cloud.devops.monitor.entity.AppResource;
import cn.abcsys.cloud.devops.monitor.model.ApplicationModel;
import cn.abcsys.cloud.devops.monitor.model.InstanceCore;
import cn.abcsys.cloud.devops.monitor.service.MonitorService;
import cn.abcsys.cloud.devops.monitor.utils.Result;

@Component("monitorService")
public class MonitorServiceImpl implements MonitorService {

	// private static final Logger LOGGER = Logger.getLogger(MonitorServiceImpl.class);

	@Autowired
	private MonitorCoreImpl monitorCore;
	@Autowired
	private SystemConfig systemConfig;
	@Autowired
	private HttpClient httpClient;
	private final static String GETALLCONTAINERSURL = "getAllContainerInfoNew.do";

	/**
	 * 应用CPU和MEM信息定时任务 具体方法
	 * 
	 * @since 2017年7月12日
	 */
	public void run() {
		// 1. 获取所有容器
		List<InstanceCore> containers = getAllContainers();
		// 2. 获取容器对应的应用信息
		Set<ApplicationModel> apps = getAllApps(containers);
		// 3. 获取整合好的 应用 -> 容器对应Hash表
		Map<ApplicationModel, List<InstanceCore>> appContainers = getAppContainers(apps, containers);
		// 4. 分析出需要保存的监控数据
		List<AppResource> ars = KeySetAppContainers(appContainers);
		ars.stream().forEach(a -> System.out.println(a.toString()));
	}

	/**
	 * 获取所有容器
	 * 
	 * @since 2017年7月12日
	 */
	@SuppressWarnings("unchecked")
	private List<InstanceCore> getAllContainers() {
		List<InstanceCore> containers = new ArrayList<>();
		Map<String, String> param = new HashMap<>();

		param.put("applicationRuntimeId", "0");
		param.put("page", "1");
		param.put("rows", "10000");

		Map<String, Object> result = httpClient.doGet(param, systemConfig.getServiceDeployer() + GETALLCONTAINERSURL);

		// 获取containers
		List<JSONObject> objs = (List<JSONObject>) result.get("rows");
		// TODO 需要修改
		objs.stream().forEach(o -> containers.add((InstanceCore) o.get("instanceCore")));

		// 各自容器获取 CPU和MEM
		JSONObject paramC = new JSONObject();
		for (InstanceCore ic : containers) {
			paramC.put("monitorType", "container");
			paramC.put("monitorItem", "cpu_used_percent");
			paramC.put("objectName", ic.getInstanceRename());
			Result cpur = monitorCore.zabbixGetImmediateData(paramC);
			if (cpur.isSuccess()) {
				ic.setCpuMonitor((Double) ((JSONObject) cpur.getData()).get("cpu_used_persent"));
			}
		}
		for (InstanceCore ic : containers) {
			paramC.put("monitorType", "container");
			paramC.put("monitorItem", "memory_used_percent");
			paramC.put("objectName", ic.getInstanceRename());
			Result cpur = monitorCore.zabbixGetImmediateData(paramC);
			if (cpur.isSuccess()) {
				ic.setMemMonitor((Double) ((JSONObject) cpur.getData()).get("mem_used_persent"));
			}
		}
		return containers;
	}

	/**
	 * 获取容器对应的应用信息
	 * 
	 * @since 2017年7月12日
	 */
	private Set<ApplicationModel> getAllApps(List<InstanceCore> containers) {
		Set<ApplicationModel> apps = new HashSet<>();
		containers.stream().forEach(
				c -> apps.add(new ApplicationModel(c.getAppId(), c.getAppName(), c.getApplicationRuntimeId())));
		return apps;
	}

	/**
	 * 获取整合好的 应用 -> 容器对应Hash表
	 * 
	 * @since 2017年7月12日
	 */
	private Map<ApplicationModel, List<InstanceCore>> getAppContainers(Set<ApplicationModel> apps,
			List<InstanceCore> containers) {
		Map<ApplicationModel, List<InstanceCore>> maps = new HashMap<>();
		for (ApplicationModel app : apps) {
			List<InstanceCore> lists = containers.stream().filter(c -> c.getAppId() == app.getAppId())
					.collect(Collectors.toList());
			maps.put(app, lists);
		}
		return maps;
	}

	/**
	 * 分析出需要保存的监控数据
	 * 
	 * @since 2017年7月12日
	 */
	private List<AppResource> KeySetAppContainers(Map<ApplicationModel, List<InstanceCore>> appContainers) {
		List<AppResource> ars = new ArrayList<>();
		for (ApplicationModel a : appContainers.keySet()) {
			List<InstanceCore> containers = appContainers.get(a);
			Double cpuMonitor = containers.stream().collect(Collectors.summingDouble(InstanceCore::getCpuMonitor));
			Double memMonitor = containers.stream().collect(Collectors.summingDouble(InstanceCore::getMemMonitor));
			AppResource ar = new AppResource(Long.valueOf(a.getAppId()), a.getApplicationCoreRename(), cpuMonitor,
					memMonitor, Long.valueOf(a.getEnvId()));
			ars.add(ar);
		}
		return ars;
	}
}
